from .import networkx_graph31 as ng31
from .import ss3_1 as s31
import time
# import ss3_1 as s31
# import networkx_graph31 as ng31
import csv
import json
import matplotlib.colors as mcolors
import math
import matplotlib.pyplot as plt
import random
import numpy as np
import pandas as pd

import networkx as nx
import configparser
import sesson1.globalvar as Globalvar
import sesson1.udp as udp
import sesson1.run as sesson1
colors = list(dict(mcolors.BASE_COLORS, **mcolors.CSS4_COLORS).keys())


class People():
    def __init__(self, speed=None, pass_point=None) -> None:
        self.speed = speed
        self.has_pass = 0
        self.pass_now_id = 0
        self.pass_id = []
        self.pass_point = pass_point
        self.cip = []
        self.target = 0
        # print(pass_point)
        # self.get_cip()

    def get_cip(self):
        for i in range(len(self.pass_point)-1):
            val = 0  # bf.GetDistance(self.pass_point[i],self.pass_point[i+1])
            self.cip.append(val)
        # print(self.cip)

    def get_pass_id(self):
        sum = 0
        for id, val in enumerate(self.cip):
            sum += val
            if(sum > self.has_pass):
                return id
        return -1


# def s32221_2json():
#     RoadLine = {
#         "places": [
#             {
#                 "place_id": 1,
#                 "people": []
#             },
#             {
#                 "place_id": 2,
#                 "people": []
#             },
#             {
#                 "place_id": 3,
#                 "people": []
#             }
#         ],
#         "operate_id": 1
#     }
#     RoadLine["operate_id"] = 3

#     for place in RoadLine["places"]:
#         place["people"] = []
#         # for peo in place["people"]:
#         #     peo["pass_points"]=[]
#     with open("name2.json", 'w', encoding='utf-8') as f:
#         f.write(json.dumps(RoadLine, ensure_ascii=False))
# s32221_2json()
# print(data_set)
def get_rate(operate_id):
    if operate_id < 25:
        return 0.96
    if operate_id < 40:
        return 0.85
    if operate_id < 50:
        return 0.7


def s31_2json(data_set, paths, place_points, operate_id, place_id, place_type):
    RoadLine = dict()
    for i in range(len(place_points)):
        temp_dict = dict()
        temp_dict["place_id"] = place_id[i]
        temp_dict["people"] = list()
        RoadLine.setdefault("places", []).append(
            temp_dict.copy())  # 根据文件大小确定答案的places个数
    RoadLine.setdefault("operate_id", operate_id)
    print("place_id ", place_id, "place_type ", place_type)
    # px = {"longitude": 105.53628319629698, "latitude": 38.832731900565818}
    # RoadLine["operate_id"] = 3
    peodic = {
        "people_id": 494,
        "people_type": 5,
        "pass_points":  []}
    # print(data_set, len(peole_path))
    asum = []
    rate = get_rate(operate_id)
    print("rate ", rate)
    for h in range(500):
        if random.uniform(0, 1) > rate:
            continue

        peodic["pass_points"] = []
        people_id = int(data_set.iloc[h]["people_id"])
        people_type = int(data_set.iloc[h]["people_type"])
        place_target_type = int(data_set.iloc[h]["place_id"])

        (p_id8, p_point, jsond3) = paths[place_target_type]
        # paths.ge
        # print(len(jsond3[0]))
        # print(paths[people_type] )
        peodic["people_id"] = people_id
        peodic["people_type"] = people_type
        # print(rd)
        peodic["pass_points"] = random.choice(jsond3)
        p_id = place_type.index(place_target_type)
        # print(p_id,place_id[p_id],place_target_type)
        # peodic["pass_points"] .append(px)  # peole_path.get(people_id)
        # peodic["pass_points"] .append(px)
        RoadLine["places"][p_id]["people"].append(peodic.copy())
        asum.append(p_id)
        # print("place_id",RoadLine["places"][p_id]["place_id"],"place_type",place_target_type)
    # print(asum)
    # spath = "D:/session/session_3/subject_2/ai_path_"+str(operate_id)+".json"
    # with open(spath, 'w', encoding='utf-8') as f:
        # f.write(json.dumps(RoadLine, ensure_ascii=False))
    # spath = "D:/session/session_3/subject_2/team_path_"+str(operate_id)+".json"

    # with open(spath, 'w', encoding='utf-8') as f:
        # f.write(json.dumps(RoadLine, ensure_ascii=False))
    # print("save path:", spath)


def getpoints_id_in_map(start_points, npallp):
    start_id = []
    danp = np.array(start_points)
    dis = []
    for s in start_points:
        dis = []
        for _val in npallp:
            # print(npallp[0])
            dis.append(s31.GetDistance(s, _val))
        start_id.append(dis.index(min(dis)))

        # minay = abs(npallp[:, 0]-_val)

        # valdis =s31 .GetDistance(points[x], points[y])

        # start_id.append(np.argmin(minay))
    return start_id


SCHOOL = 1
# def gen_place(place_type,operate_id):
#     plen = len(place_type)


#     print(place_type)
#     people_place_id = []
#     if plen == 3:  # 3个地点
#         if SCHOOL in place_type:  # 有学校
#             people_place_id += [SCHOOL for i in range(92)]  # 学校90
#             for val in place_type:
#                 if val == SCHOOL:
#                     continue
#                 people_place_id += [val for i in range(206)]
#                 print(len(people_place_id), val)
#         else:
#             people_place_id = [random.choice(place_type) for i in range(500)]
#     elif plen == 5:
#         if SCHOOL in place_type:  # 有学校
#             people_place_id += [SCHOOL for i in range(68)]  # 学校90

#             for val in place_type:
#                 if val == SCHOOL:
#                     continue
#                 if val == 5:
#                     continue

#                 people_place_id += [val for i in range(144)]
#                 print(len(people_place_id), val)
#         else:
#             people_place_id = [random.choice(place_type) for i in range(500)]
#     elif plen == 4:
#         if SCHOOL in place_type:  # 有学校
#             people_place_id += [SCHOOL for i in range(80)]  # 学校90
#             for val in place_type:
#                 if val == SCHOOL:
#                     continue
#                 if val == 5:
#                     continue
#                 people_place_id += [val for i in range(140)]
#                 print(len(people_place_id), val)
#         else:
#             people_place_id = [random.choice(place_type) for i in range(500)]
#     else:
#         people_place_id = [random.choice(place_type) for i in range(500)]

#     # print(people_place_id)
#     return people_place_id[:500]

def gen_place(place_type, operate_id, place__index):
    plen = len(place_type)

    # print(place_type,place__index)
    people_place_id = []
    if plen == 3:  # 3个地点
        if SCHOOL in place_type:  # 有学校
            people_place_id += [SCHOOL for i in range(92)]  # 学校90
            for val in place_type:
                if val == SCHOOL:
                    continue
                people_place_id += [val for i in range(206)]
                # print(len(people_place_id), val)
        else:
            people_place_id = [random.choice(place_type) for i in range(500)]
    elif plen == 5:
        if SCHOOL in place_type:  # 有学校
            people_place_id += [SCHOOL for i in range(68)]  # 学校90

            for val in place_type:
                if val == SCHOOL:
                    continue
                if val == 5:
                    continue

                people_place_id += [val for i in range(144)]
                # print(len(people_place_id), val)
        else:
            people_place_id = [random.choice(place_type) for i in range(500)]
    elif plen == 4:
        if SCHOOL in place_type:  # 有学校
            people_place_id += [SCHOOL for i in range(80)]  # 学校90
            for val in place_type:
                if val == SCHOOL:
                    continue
                if val == 5:
                    continue
                people_place_id += [val for i in range(140)]
                print(len(people_place_id), val)
        else:
            people_place_id = [random.choice(place_type) for i in range(500)]
    else:
        people_place_id = [random.choice(place_type) for i in range(500)]

    # print(people_place_id)
    return people_place_id[:500]


def data2pandfram(data_set, place_type, operate_id, place__index, _columns=['place_id']):
    # people_type = data_set["people_type"].to_list()
    # people_place_id = []

    # if 4 in place_type:
    #     yiyuan_id = 4
    # else:
    #     yiyuan_id =random.choice(place_type)
    # for pt in people_type:
    #     if pt == 5:
    #         people_place_id.append(yiyuan_id)
    #     else:
    #         people_place_id.append(random.randint(1, 3))
    # print(place_type)
    people_place_id = gen_place(place_type, operate_id, place__index)
    data3 = pd.DataFrame(np.array(people_place_id), columns=_columns)

    data_set = pd.concat([data_set, data3], axis=1)
    # print(data_set)
    return data_set


def preprocess(Objdll, s1, ipconfigPath):
    # 读图
    cf = configparser.ConfigParser()
    cf.read(ipconfigPath+"/ipconfig.ini")
    local_ip = cf.get("entrant", "ip")
    local_port = cf.get("entrant", "port")
    s1.bind((local_ip, int(local_port)))  # 绑定ip和端口
    # 设置发送（客户端）的ip和端口
    client_ip = cf.get("client", "ip")
    client_port = cf.get("client", "port")
    dest_dir = (client_ip, int(client_port))
    Globalvar.set_send_id_addr(dest_dir)
    # local_ip = udp.socket.gethostbyname(udp.socket.gethostname())
    # s1.bind((local_ip, 10014))
    # print("local_ip:",local_ip)
    print('Bind UDP on 10014...')
    # 创建线程接收数据
    recv_thread = udp.threading.Thread(target=udp.recvmsg, args=(s1, Objdll))
    recv_thread.start()
    return True


def session_3_1_main(Objdll, s):
    f = open("./exam-round-record1.txt", "r")
    next_round = f.read()
    exam_round = int(next_round)
    print("current exam round: " + str(exam_round))
    # exam_round = 1
    # 判断每场考试是否结束，结束为true，否则为false，初始为true方便第一次发送
    finish = True
    while True:
        if finish:
            # 发送准备指令
            sesson1.send_ready(3, 1, exam_round, s)
            finish = False
        if Globalvar.get_recv_msg_content():
            Globalvar.set_recv_msg_content(False)
            # 根据报文读取对应科目、情景下的client_path_.json文件
            temp_content = Globalvar.get_msg_content_value()
            examRound = Globalvar.get_exam_round()
            view_ai_path(examRound)  # 算法主程序
            # client_path_content = read_client_path(temp_content[0], temp_content[1], exam_round=examRound)
            # if dlltest.transfer_client_path(Objdll, client_path_content, temp_content[0], temp_content[1]):
            # 数据传入完成，算法计算完毕，向平台发送完成指令
            udp.sentmsg(temp_content[0], temp_content[1], s, Globalvar.get_send_id_addr(
            ), exam_round=examRound, info=3)
            finish = True
            # 一场考试结束后将考试场次+1
            exam_round += 1
            with open("./exam-round-record1.txt", "w") as f:  # 记录下一次的考试场次
                f.write(str(exam_round))
            print("运行成功，准备下次考试")


def view_ai_path(operate_id=1001):  # main
    client_path = "D:/session/session_3/subject_2/client_path_" + \
        str(operate_id)+".json"

    data_set, start_points, place_points, break_points, (place__index, place_type) = s31.read_client_data(
        client_path)
    points, roadLines, roadpoint = ng31. view_maps2(True)  # 读取地图
    out_edges, dictpoints = ng31.perdata(roadLines, points)  # 修正数据
    gant = nx.Graph()  # 创建：空的 无向图
    gant.add_weighted_edges_from(out_edges)  # 向图中添加多条赋权边: (node1,node2,weight)

    npallp = np.array(points)
    # print("start_points:", start_points)
    start_id = getpoints_id_in_map(start_points, npallp)
    place_id = getpoints_id_in_map(place_points, npallp)
    break_id = getpoints_id_in_map(break_points, npallp)
    # print("start_id ",start_id,"place_id ",place_id,"break_id ",break_id)

  # print(points)
    out_edges = []
    for x, y in roadpoint:
        # print(x,y)
        if(points[x] == points[y]):
            out_edges.append((x, y, 0.000))
            continue
        valdis = s31 .GetDistance(points[x], points[y])
        if(valdis < 7):
            out_edges.append((x, y, valdis))
            continue
    gant.add_weighted_edges_from(out_edges)  # 向图中添加多条赋权边: (node1,node2,weight)
    # nx.draw(gant, dictpoints, with_labels=False,node_size=5)  # , alpha=0.8

    roadpoint_np = np.array(roadpoint)
    for i, bi in enumerate(break_id):
        roadpoint_index = (roadpoint_np[:, 1] == bi)
        if len(roadpoint_np[roadpoint_index]) > 0:
            # print(roadpoint_np[roadpoint_index],roadpoint_np[roadpoint_index][0][1],i)
            break_id[i] = roadpoint_np[roadpoint_index][0][0]

    rd_edges = []
    for i in range(int(len(break_id)*0.5)):
        rd_edges.append(nx.astar_path(gant, break_id[2*i], break_id[2*i+1]))
    for eg in rd_edges:
        for val in range(len(eg)-1):
            # print(eg[ val],eg[val+1])
            gant.remove_edge(eg[val], eg[val+1])

    paths = dict()
    for ii, eid in enumerate(place_id):
        path = []
        for sid in start_id:
            path.append(nx.astar_path(gant, sid, eid))
        paths[place_type[ii]] = path.copy()

    data_set = data2pandfram(data_set, place_type,
                             operate_id, place__index, _columns=["place_id"])
    # print(data_set)
    s31.id2points(paths, points, place__index)
    s31_2json(data_set, paths, place_points,
              operate_id, place__index, place_type)

    return paths, points

    # for place in RoadLine["places"]:
    #     for peo in place["people"]:
    #         # p0=People(speed=1,pass_point=[])
    #         # p0.people_id=peo["people_id"]
    #         path=[]
    #         place_id[peo["people_id"]-1]=place["place_id"]
    #         # p0.people_type=peo["people_type"]
    #         # print(p0.people_id)
    #         # peoples.append(p0)
    #         for _path in peo["pass_points"]:
    #             path.append([_path["longitude"],_path["latitude"]])
    #         peole_path.setdefault(peo["people_id"],path)
    # data3 = pd.DataFrame(np.array(place_id), columns=['place_id'])
    # data_set = pd.concat([data_set, data3], axis=1)
    # print(data_set)
    # for i in range(10):
    #     dt=peole_path.get(i)
    #     if(dt!=None):
    #         # print(dt[0])
    #         pass
    # # data_set.to_csv('example.csv')#保存完毕
    #
    # return place_id,peole_path


if __name__ == '__main__':
    view_ai_path(1)
